Purpose:

Runs survival analysis models using splicing cluster assignment and 1) single exon splicing burden index (SBI) 2) KEGG Spliceosome GSVA scores or 3) CLK1 exon 4 TPM as a predictor

Usage

Uses a wrapper function (survival_analysis) from utils folder.

Setup

Packages and functions

Load packages, set directory paths and call setup script

library(tidyverse)
── Attaching core tidyverse packages ───────────────────────────────────────────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.6
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.1     ✔ tibble    3.3.0
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.2.0     
── Conflicts ─────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(survival)
library(ggpubr)
library(ggplot2)
library(patchwork)

root_dir <- rprojroot::find_root(rprojroot::has_dir(".git"))

data_dir <- file.path(root_dir, "data")
analysis_dir <- file.path(root_dir, "analyses", "survival")
input_dir <- file.path(analysis_dir, "results")
results_dir <- file.path(analysis_dir, "results")
plot_dir <- file.path(analysis_dir, "plots")

# If the input and results directories do not exist, create it
if (!dir.exists(results_dir)) {
  dir.create(results_dir, recursive = TRUE)
}

source(file.path(analysis_dir, "util", "survival_models.R"))

Attaching package: 'survminer'

The following object is masked from 'package:survival':

    myeloma

Set metadata and cluster assignment file paths

metadata_file <- file.path(input_dir, "splicing_indices_with_survival.tsv")

cluster_file <- file.path(root_dir, "analyses",
                          "sample-psi-clustering", "results",
                          "sample-cluster-metadata-top-5000-events-stranded.tsv")

kegg_scores_stranded_file <- file.path(root_dir, "analyses",
                          "sample-psi-clustering", "results",
                          "gsva_output_stranded.tsv")

tpm_file <- file.path(data_dir, "rna-isoform-expression-rsem-tpm.rds")
clk1_psi_file <- file.path(root_dir, 
                           "analyses", 
                           "CLK1-splicing_correlations", 
                           "results", 
                           "clk1-exon4-psi.tsv")

Wrangle data Add cluster assignment and spliceosome gsva scores to metadata and define column lgg_group (LGG or non_LGG)

metadata <- read_tsv(metadata_file)
Rows: 684 Columns: 26
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (11): Kids_First_Biospecimen_ID, Histology, Kids_First_Participant_ID, m...
dbl (15): Total, AS_neg, AS_pos, AS_total, SI_A3SS, SI_A5SS, SI_RI, SI_SE, S...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
clusters <- read_tsv(cluster_file) %>%
  dplyr::rename(Kids_First_Biospecimen_ID = sample_id)
Rows: 729 Columns: 8
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (6): sample_id, plot_group, plot_group_hex, RNA_library, molecular_subty...
dbl (2): cluster, group_n

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
clk1_psi <- read_tsv(clk1_psi_file) %>%
  dplyr::rename(CLK1_ex4_PSI = PSI) %>%
  select(-plot_group)
Rows: 752 Columns: 3
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (2): Kids_First_Biospecimen_ID, plot_group
dbl (1): PSI

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
gsva_scores <- read_tsv(kegg_scores_stranded_file) %>%
  dplyr::filter(geneset == "KEGG_SPLICEOSOME") %>%
  dplyr::rename(spliceosome_gsva_score = score)
Rows: 22599 Columns: 3
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: "\t"
chr (2): sample_id, geneset
dbl (1): score

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
all_clk4_transcr_counts <- readRDS(tpm_file) %>%
  filter(grepl("^CLK1", gene_symbol)) %>%
  mutate(
    transcript_id = case_when(
      transcript_id %in% c("ENST00000321356.9", "ENST00000434813.3", "ENST00000409403.6") ~ "Exon 4",
#      transcript_id == "ENST00000321356.9" ~ "Exon 4",
      TRUE ~ "Other"
    )
  ) %>%
  group_by(transcript_id) %>%
  summarise(across(starts_with("BS"), sum, na.rm = TRUE)) %>%
  pivot_longer(cols = -transcript_id, names_to = "Kids_First_Biospecimen_ID", values_to = "CLK1_Ex4_TPM") %>%
  filter(transcript_id == "Exon 4") %>%
  inner_join(clusters, by = "Kids_First_Biospecimen_ID") %>%
  left_join(clk1_psi)
Warning: There was 1 warning in `summarise()`.
ℹ In argument: `across(starts_with("BS"), sum, na.rm = TRUE)`.
ℹ In group 1: `transcript_id = "Exon 4"`.
Caused by warning:
! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
Supply arguments directly to `.fns` through an anonymous function instead.

  # Previously
  across(a:b, mean, na.rm = TRUE)

  # Now
  across(a:b, \(x) mean(x, na.rm = TRUE))
Joining with `by = join_by(Kids_First_Biospecimen_ID)`
# how many clusters?
n_clust <- length(unique(clusters$cluster))

metadata <- metadata %>%
  right_join(all_clk4_transcr_counts %>% dplyr::select(Kids_First_Biospecimen_ID,
                                       cluster, CLK1_Ex4_TPM, CLK1_ex4_PSI)) %>%
  left_join(gsva_scores %>% dplyr::select(sample_id,
                                          spliceosome_gsva_score),
            by = c("Kids_First_Biospecimen_ID" = "sample_id")) %>% 
  dplyr::mutate(cluster = glue::glue("Cluster {cluster}")) %>%
  dplyr::mutate(cluster = fct_relevel(cluster,
                                               paste0("Cluster ", 1:n_clust))) %>%
  dplyr::mutate(lgg_group = case_when(
    plot_group == "Low-grade glioma" ~ "LGG",
    TRUE ~ "non-LGG"
  )) %>%
  dplyr::mutate(SBI = SI_Total * 10) %>%
  dplyr::mutate(age_at_diagnosis_years = age_at_diagnosis_days/365.25)
Joining with `by = join_by(Kids_First_Biospecimen_ID)`

Generate coxph models including extent of tumor resection, lgg group, cluster assignment, SBI, and CLK1 exon 4 TPM as covariates

add_model_os <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                              terms = "extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+SBI+CLK1_Ex4_TPM",
                               file.path(results_dir, "cox_OS_additive_terms_resection_lgg_group_cluster_SBI_CLK1_Ex4_TPM.RDS"),
                               "multivariate",
                               years_col = "OS_years",
                               status_col = "OS_status")

forest_os <- plotForest(readRDS(file.path(results_dir, "cox_OS_additive_terms_resection_lgg_group_cluster_SBI_CLK1_Ex4_TPM.RDS")))
Warning: `geom_errorbarh()` was deprecated in ggplot2 4.0.0.
ℹ Please use the `orientation` argument of `geom_errorbar()` instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
ℹ Please use the `linewidth` argument instead.
ℹ The deprecated feature was likely used in the ggpubr package.
  Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
Warning: The `size` argument of `element_rect()` is deprecated as of ggplot2 3.4.0.
ℹ Please use the `linewidth` argument instead.
ℹ The deprecated feature was likely used in the ggpubr package.
  Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
`height` was translated to `width`.
Warning: The `guide` argument in `scale_*()` cannot be `FALSE`. This was deprecated in ggplot2 3.3.4.
ℹ Please use "none" instead.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

forest_os

ggsave(file.path(plot_dir, "forest_add_OS_resection_lgg_group_cluster_assignment_SBI_CLK1_Ex4_TPM.pdf"),
       forest_os,
       width = 10, height = 6, units = "in",
       device = "pdf")

add_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                              terms = "extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+SBI+CLK1_Ex4_TPM",
                               file.path(results_dir, "cox_EFS_additive_terms_resection_lgg_group_cluster_SBI_CLK1_Ex4_TPM.RDS"),
                               "multivariate",
                               years_col = "EFS_years",
                               status_col = "EFS_status")

forest_efs <- plotForest(readRDS(file.path(results_dir, "cox_EFS_additive_terms_resection_lgg_group_cluster_SBI_CLK1_Ex4_TPM.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

forest_efs

ggsave(file.path(plot_dir, "forest_add_EFS_resection_lgg_group_cluster_assignment_SBI_CLK1_Ex4_TPM.pdf"),
       forest_efs,
       width = 10, height = 6, units = "in",
       device = "pdf")

repeat analysis with CLK1 exon 4 TPM alone

add_model_os <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                              terms = "extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+CLK1_Ex4_TPM",
                               file.path(results_dir, "cox_OS_additive_terms_resection_lgg_group_cluster_CLK1_Ex4_TPM.RDS"),
                               "multivariate",
                               years_col = "OS_years",
                               status_col = "OS_status")

forest_os <- plotForest(readRDS(file.path(results_dir, "cox_OS_additive_terms_resection_lgg_group_cluster_CLK1_Ex4_TPM.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

forest_os

ggsave(file.path(plot_dir, "forest_add_OS_resection_lgg_group_cluster_assignment_CLK1_Ex4_TPM.pdf"),
       forest_os,
       width = 10, height = 6, units = "in",
       device = "pdf")


add_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                              terms = "extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+CLK1_Ex4_TPM",
                               file.path(results_dir, "cox_EFS_additive_terms_resection_lgg_group_cluster_CLK1_Ex4_TPM.RDS"),
                               "multivariate",
                               years_col = "EFS_years",
                               status_col = "EFS_status")

forest_efs <- plotForest(readRDS(file.path(results_dir, "cox_EFS_additive_terms_resection_lgg_group_cluster_CLK1_Ex4_TPM.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

forest_efs

ggsave(file.path(plot_dir, "forest_add_EFS_resection_lgg_group_cluster_assignment_CLK1_Ex4_TPM.pdf"),
       forest_efs,
       width = 10, height = 6, units = "in",
       device = "pdf")

repeat analysis with CLK1 exon 4 PSI

add_model_os <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                              terms = "extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+CLK1_ex4_PSI",
                               file.path(results_dir, "cox_OS_additive_terms_resection_lgg_group_cluster_CLK1_ex4_PSI.RDS"),
                               "multivariate",
                               years_col = "OS_years",
                               status_col = "OS_status")

forest_os <- plotForest(readRDS(file.path(results_dir, "cox_OS_additive_terms_resection_lgg_group_cluster_CLK1_ex4_PSI.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

forest_os

ggsave(file.path(plot_dir, "forest_add_OS_resection_lgg_group_cluster_assignment_CLK1_ex4_PSI.pdf"),
       forest_os,
       width = 10, height = 6, units = "in",
       device = "pdf")

add_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                              terms = "extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+CLK1_ex4_PSI",
                               file.path(results_dir, "cox_EFS_additive_terms_resection_lgg_group_cluster_CLK1_ex4_PSI.RDS"),
                               "multivariate",
                               years_col = "EFS_years",
                               status_col = "EFS_status")

forest_efs <- plotForest(readRDS(file.path(results_dir, "cox_EFS_additive_terms_resection_lgg_group_cluster_CLK1_ex4_PSI.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

forest_efs

ggsave(file.path(plot_dir, "forest_add_EFS_resection_lgg_group_cluster_assignment_CLK1_ex4_PSI.pdf"),
       forest_efs,
       width = 10, height = 6, units = "in",
       device = "pdf")

Interaction with GSVA, SBI, CLK1

models <- c("spliceosome_gsva_score", "SBI", "CLK1_Ex4_TPM", "CLK1_ex4_PSI")
# by cluster
for (each in models) {
  int_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                                terms = paste0("extent_of_tumor_resection+lgg_group+cluster*", each, "+age_at_diagnosis_years"),
                                 file.path(results_dir, paste0("cox_EFS_interaction_terms_resection_lgg_group_cluster_", each, ".RDS")),
                                 "multivariate",
                                 years_col = "EFS_years",
                                 status_col = "EFS_status")
  
  int_forest_efs <- plotForest(readRDS(file.path(results_dir, paste0("cox_EFS_interaction_terms_resection_lgg_group_cluster_", each, ".RDS"))))
  
  int_forest_efs
  
  ggsave(file.path(plot_dir, paste0("forest_int_EFS_resection_lgg_group_cluster_assignment_", each, ".pdf")),
         int_forest_efs,
         width = 10, height = 6, units = "in",
         device = "pdf")

  int_model_os <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                                terms = paste0("extent_of_tumor_resection+lgg_group+cluster*", each, "+age_at_diagnosis_years"),
                                 file.path(results_dir, paste0("cox_OS_interaction_terms_resection_lgg_group_cluster_", each, ".RDS")),
                                 "multivariate",
                                 years_col = "OS_years",
                                 status_col = "OS_status")
  
  int_forest_os <- plotForest(readRDS(file.path(results_dir, paste0("cox_OS_interaction_terms_resection_lgg_group_cluster_", each, ".RDS"))))
  
  int_forest_os
  
  ggsave(file.path(plot_dir, paste0("forest_int_OS_resection_lgg_group_cluster_assignment_", each, ".pdf")),
         int_forest_os,
         width = 10, height = 6, units = "in",
         device = "pdf")
}
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

## clk1 x age
  int_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                                terms = paste0("extent_of_tumor_resection+lgg_group+cluster+CLK1_Ex4_TPM*age_at_diagnosis_years"),
                                 file.path(results_dir, paste0("cox_EFS_interaction_terms_resection_lgg_group_cluster_CLK1_Ex4_TPM_age.RDS")),
                                 "multivariate",
                                 years_col = "EFS_years",
                                 status_col = "EFS_status")
  
  int_forest_efs <- plotForest(readRDS(file.path(results_dir, paste0("cox_EFS_interaction_terms_resection_lgg_group_cluster_CLK1_Ex4_TPM_age.RDS"))))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

  int_forest_efs

  ggsave(file.path(plot_dir, paste0("forest_int_EFS_resection_lgg_group_cluster_clk1_age.pdf")),
         int_forest_efs,
         width = 10, height = 6, units = "in",
         device = "pdf")

  int_model_os <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                                terms = paste0("extent_of_tumor_resection+lgg_group+cluster+CLK1_Ex4_TPM*age_at_diagnosis_years"),
                                 file.path(results_dir, paste0("cox_OS_interaction_terms_resection_lgg_group_cluster_clk1_age.RDS")),
                                 "multivariate",
                                 years_col = "OS_years",
                                 status_col = "OS_status")
  
  int_forest_os <- plotForest(readRDS(file.path(results_dir, paste0("cox_OS_interaction_terms_resection_lgg_group_cluster_clk1_age.RDS"))))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

  int_forest_os

  ggsave(file.path(plot_dir, paste0("forest_int_OS_resection_lgg_group_cluster_clk1_age.pdf")),
         int_forest_os,
         width = 10, height = 6, units = "in",
         device = "pdf")

models2 <- c("SBI", "CLK1_Ex4_TPM")
for (each in models2) {
  #### by spliceosome_gsva_score
  int_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                                terms = paste0("extent_of_tumor_resection+lgg_group+cluster+spliceosome_gsva_score*", each, "+age_at_diagnosis_years"),
                                 file.path(results_dir, paste0("cox_EFS_interaction_terms_resection_lgg_group_cluster_spliceosome_gsva_score_", each, ".RDS")),
                                 "multivariate",
                                 years_col = "EFS_years",
                                 status_col = "EFS_status")
  
  int_forest_efs <- plotForest(readRDS(file.path(results_dir, paste0("cox_EFS_interaction_terms_resection_lgg_group_cluster_spliceosome_gsva_score_", each, ".RDS"))))
  
  int_forest_efs
  
  ggsave(file.path(plot_dir, paste0("cox_EFS_interaction_terms_resection_lgg_group_cluster_spliceosome_gsva_score_", each, ".pdf")),
         int_forest_efs,
         width = 10, height = 6, units = "in",
         device = "pdf")
}
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

add_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                              terms = "extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+spliceosome_gsva_score+CLK1_Ex4_TPM",
                               file.path(results_dir, "cox_EFS_additive_terms_resection_lgg_group_cluster_spliceosome_score_CLK1_Ex4_TPM.RDS"),
                               "multivariate",
                               years_col = "EFS_years",
                               status_col = "EFS_status")

forest_efs <- plotForest(readRDS(file.path(results_dir, "cox_EFS_additive_terms_resection_lgg_group_cluster_spliceosome_score_CLK1_Ex4_TPM.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

forest_efs

ggsave(file.path(plot_dir, "forest_add_EFS_resection_lgg_group_cluster_assignment_spliceosome_score_CLK1_Ex4_TPM.pdf"),
       forest_efs,
       width = 10, height = 6, units = "in",
       device = "pdf")


add_model_os <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c("Not Reported", "Unavailable"),],
                              terms = "extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+spliceosome_gsva_score+CLK1_Ex4_TPM",
                               file.path(results_dir, "cox_OS_additive_terms_resection_lgg_group_cluster_spliceosome_score_CLK1_Ex4_TPM.RDS"),
                               "multivariate",
                               years_col = "EFS_years",
                               status_col = "EFS_status")

forest_os <- plotForest(readRDS(file.path(results_dir, "cox_OS_additive_terms_resection_lgg_group_cluster_spliceosome_score_CLK1_Ex4_TPM.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

forest_os

ggsave(file.path(plot_dir, "forest_add_OS_resection_lgg_group_cluster_assignment_spliceosome_score_CLK1_Ex4_TPM.pdf"),
       forest_efs,
       width = 10, height = 6, units = "in",
       device = "pdf")

Filter for cluster 7

cluster7_df <- metadata %>%
  dplyr::filter(cluster == "Cluster 7",
                !is.na(EFS_days)) %>%
  dplyr::mutate(CLK1_TPM_group = case_when(
      CLK1_Ex4_TPM > summary(CLK1_Ex4_TPM)["3rd Qu."] ~ "High CLK1 TPM",
      CLK1_Ex4_TPM < summary(CLK1_Ex4_TPM)["1st Qu."] ~ "Low CLK1 TPM",
      TRUE ~ NA_character_),
      CLK1_PSI_group = case_when(CLK1_ex4_PSI > summary(CLK1_ex4_PSI)["3rd Qu."] ~ "High CLK1 PSI",
      CLK1_ex4_PSI < summary(CLK1_ex4_PSI)["1st Qu."] ~ "Low CLK1 PSI",
      TRUE ~ NA_character_
    )) %>%
  dplyr::mutate(CLK1_TPM_group = fct_relevel(CLK1_TPM_group,
                                                 c("Low CLK1 TPM", "High CLK1 TPM")),
                CLK1_PSI_group = fct_relevel(CLK1_PSI_group,
                                                 c("Low CLK1 PSI", "High CLK1 PSI")))

Generate KM models with CLK1_TPM_group as covariate

# Generate kaplan meier survival models for OS and EFS, and save outputs
c7_clk_tpm_kap_os <- survival_analysis(
  metadata  = cluster7_df %>% 
    dplyr::filter(!is.na(CLK1_TPM_group)),
  ind_var = "CLK1_TPM_group",
  test = "kap.meier",
  metadata_sample_col = "Kids_First_Biospecimen_ID",
  days_col = "OS_days",
  status_col = "OS_status"
)
Warning: Using an external vector in selections was deprecated in tidyselect 1.1.0.
ℹ Please use `all_of()` or `any_of()` instead.
  # Was:
  data %>% select(ind_var)

  # Now:
  data %>% select(all_of(ind_var))

See <https://tidyselect.r-lib.org/reference/faq-external-vector.html>.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
Testing model: survival::Surv(OS_days, OS_status) ~ CLK1_TPM_group with kap.meier
readr::write_rds(c7_clk_tpm_kap_os,
                 file.path(results_dir, "logrank_cluster7_OS_clk1_tpm_group.RDS"))

c7_clk_tpm_kap_efs <- survival_analysis(
  metadata  = cluster7_df %>% 
    dplyr::filter(!is.na(CLK1_TPM_group)),
  ind_var = "CLK1_TPM_group",
  test = "kap.meier",
  metadata_sample_col = "Kids_First_Biospecimen_ID",
  days_col = "EFS_days",
  status_col = "EFS_status"
)
Testing model: survival::Surv(EFS_days, EFS_status) ~ CLK1_TPM_group with kap.meier
readr::write_rds(c7_clk_tpm_kap_efs,
                 file.path(results_dir, "logrank_cluster7_EFS_clk1_tpm_group.RDS"))

Generate KM models with CLK1_PSI_group as covariate

# Generate kaplan meier survival models for OS and EFS, and save outputs
c7_clk_psi_kap_os <- survival_analysis(
  metadata  = cluster7_df %>% 
    dplyr::filter(!is.na(CLK1_PSI_group)),
  ind_var = "CLK1_PSI_group",
  test = "kap.meier",
  metadata_sample_col = "Kids_First_Biospecimen_ID",
  days_col = "OS_days",
  status_col = "OS_status"
)
Testing model: survival::Surv(OS_days, OS_status) ~ CLK1_PSI_group with kap.meier
readr::write_rds(c7_clk_psi_kap_os,
                 file.path(results_dir, "logrank_cluster7_OS_clk1_psi_group.RDS"))

c7_clk_psi_kap_efs <- survival_analysis(
  metadata  = cluster7_df %>% 
    dplyr::filter(!is.na(CLK1_PSI_group)),
  ind_var = "CLK1_PSI_group",
  test = "kap.meier",
  metadata_sample_col = "Kids_First_Biospecimen_ID",
  days_col = "EFS_days",
  status_col = "EFS_status"
)
Testing model: survival::Surv(EFS_days, EFS_status) ~ CLK1_PSI_group with kap.meier
readr::write_rds(c7_clk_psi_kap_efs,
                 file.path(results_dir, "logrank_cluster7_EFS_clk1_psi_group.RDS"))

Generate cluster 7 KM SI_group plots

km_c7_clk_tpm_os_plot <- plotKM(model = c7_clk_tpm_kap_os,
                    variable = "CLK1_TPM_group",
                    combined = F, 
                    title = "Cluster 7, overall survival",
                    p_pos = "topright")
Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
ℹ Please use tidy evaluation idioms with `aes()`.
ℹ See also `vignette("ggplot2-in-packages")` for more information.
ℹ The deprecated feature was likely used in the survminer package.
  Please report the issue at <https://github.com/kassambara/survminer/issues>.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
ℹ The deprecated feature was likely used in the ggpubr package.
  Please report the issue at <https://github.com/kassambara/ggpubr/issues>.
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
Ignoring unknown labels:
• fill : ""
Warning: No shared levels found between `names(values)` of the manual scale and
the data's fill values.
ggsave(file.path(plot_dir, "km_cluster7_OS_clk1_tpm_group.pdf"),
       km_c7_clk_tpm_os_plot,
       width = 8, height = 5, units = "in",
       device = "pdf")
Ignoring unknown labels:
• fill : ""
Warning: No shared levels found between `names(values)` of the manual scale and
the data's fill values.
Ignoring unknown labels:
• colour : ""
Warning: No shared levels found between `names(values)` of the manual scale and
the data's colour values.
Warning: No shared levels found between `names(values)` of the manual scale and
the data's fill values.
km_c7_clk1_tpm_efs_plot <- plotKM(model = c7_clk_tpm_kap_efs,
                    variable = "CLK1_TPM_group",
                    combined = F, 
                    title = "Cluster 7, event-free survival",
                    p_pos = "topright")
Ignoring unknown labels:
• fill : ""
Warning: No shared levels found between `names(values)` of the manual scale and
the data's fill values.
ggsave(file.path(plot_dir, "km_cluster7_EFS_clk1_tpm_group.pdf"), 
       km_c7_clk1_tpm_efs_plot,
       width = 8, height = 5, units = "in",
       device = "pdf")
Ignoring unknown labels:
• fill : ""
Warning: No shared levels found between `names(values)` of the manual scale and
the data's fill values.
Ignoring unknown labels:
• colour : ""
Warning: No shared levels found between `names(values)` of the manual scale and the data's colour values.
No shared levels found between `names(values)` of the manual scale and the data's fill values.
km_c7_clk1_psi_os_plot <- plotKM(model = c7_clk_psi_kap_os,
                    variable = "CLK1_PSI_group",
                    combined = F, 
                    title = "Cluster 7, overall survival",
                    p_pos = "topright")
Ignoring unknown labels:
• fill : ""
Warning: No shared levels found between `names(values)` of the manual scale and
the data's fill values.
ggsave(file.path(plot_dir, "km_cluster7_OS_clk1_psi_group.pdf"),
       km_c7_clk1_psi_os_plot,
       width = 8, height = 5, units = "in",
       device = "pdf")
Ignoring unknown labels:
• fill : ""
Warning: No shared levels found between `names(values)` of the manual scale and
the data's fill values.
Ignoring unknown labels:
• colour : ""
Warning: No shared levels found between `names(values)` of the manual scale and the data's colour values.
No shared levels found between `names(values)` of the manual scale and the data's fill values.
km_c7_clk1_psi_efs_plot <- plotKM(model = c7_clk_psi_kap_efs,
                    variable = "CLK1_PSI_group",
                    combined = F, 
                    title = "Cluster 7, event-free survival",
                    p_pos = "topright")
Ignoring unknown labels:
• fill : ""
Warning: No shared levels found between `names(values)` of the manual scale and
the data's fill values.
ggsave(file.path(plot_dir, "km_cluster7_EFS_clk1_psi_group.pdf"), 
       km_c7_clk1_psi_efs_plot,
       width = 8, height = 5, units = "in",
       device = "pdf")
Ignoring unknown labels:
• fill : ""
Warning: No shared levels found between `names(values)` of the manual scale and
the data's fill values.
Ignoring unknown labels:
• colour : ""
Warning: No shared levels found between `names(values)` of the manual scale and the data's colour values.
No shared levels found between `names(values)` of the manual scale and the data's fill values.

Assess EFS and OS by CLK1 TPM group in multivariate models and generate forest plots

add_model_c7_efs <- fit_save_model(cluster7_df %>% 
                                      dplyr::filter(extent_of_tumor_resection != "Unavailable",
                                                    CLK1_TPM_group %in% c("High CLK1 TPM", "Low CLK1 TPM")) %>%
                                      dplyr::mutate(plot_group = fct_relevel(plot_group,
                                                                            c("Other high-grade glioma", "Atypical Teratoid Rhabdoid Tumor",
                                                                              "DIPG or DMG", "Ependymoma", "Mesenchymal tumor",
                                                                              "Other CNS embryonal tumor", "Low-grade glioma"))),
                              terms = "extent_of_tumor_resection+age_at_diagnosis_years+plot_group+CLK1_TPM_group",
                               file.path(results_dir, "cox_EFS_additive_terms_subtype_cluster_clk1_tpm_group.RDS"),
                               "multivariate",
                               years_col = "EFS_years",
                               status_col = "EFS_status")
Warning: There was 1 warning in `dplyr::mutate()`.
ℹ In argument: `plot_group = fct_relevel(...)`.
Caused by warning:
! 3 unknown levels in `f`: Atypical Teratoid Rhabdoid Tumor, DIPG or DMG, and Mesenchymal tumor
forest_c7_clk1_efs <- plotForest(readRDS(file.path(results_dir, "cox_EFS_additive_terms_subtype_cluster_clk1_tpm_group.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

ggsave(file.path(plot_dir, "forest_add_EFS_cluster7_histology_resection_clk1_tpm_group.pdf"),
       forest_c7_clk1_efs,
       width = 9, height = 4, units = "in",
       device = "pdf")

add_model_c7_os <- fit_save_model(cluster7_df %>% 
                                    dplyr::filter(!extent_of_tumor_resection %in% c("Not Reported", "Unavailable")) %>%
                                    dplyr::mutate(plot_group = fct_relevel(plot_group,
                                                                            c("Other high-grade glioma", "Atypical Teratoid Rhabdoid Tumor",
                                                                              "DIPG or DMG", "Ependymoma", "Mesenchymal tumor",
                                                                              "Other CNS embryonal tumor", "Low-grade glioma"))),
                              terms = "extent_of_tumor_resection+age_at_diagnosis_years+plot_group+CLK1_TPM_group",
                               file.path(results_dir, "cox_OS_additive_terms_subtype_cluster_clk1_tpm_group.RDS"),
                               "multivariate",
                               years_col = "OS_years",
                               status_col = "OS_status")
Warning: There was 1 warning in `dplyr::mutate()`.
ℹ In argument: `plot_group = fct_relevel(...)`.
Caused by warning:
! 3 unknown levels in `f`: Atypical Teratoid Rhabdoid Tumor, DIPG or DMG, and Mesenchymal tumor
Warning in coxph.fit(X, Y, istrat, offset, init, control, weights = weights, :
Ran out of iterations and did not converge
forest_c7_clk1_os <- plotForest(readRDS(file.path(results_dir, "cox_OS_additive_terms_subtype_cluster_clk1_tpm_group.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

ggsave(file.path(plot_dir, "forest_add_OS_cluster7_histology_resection_clk1_tpm_group.pdf"),
       forest_c7_clk1_os,
       width = 9, height = 4, units = "in",
       device = "pdf")

Assess EFS and OS by CLK1 PSI group in multivariate models and generate forest plots

add_model_c7_efs <- fit_save_model(cluster7_df %>% 
                                      dplyr::filter(extent_of_tumor_resection != "Unavailable",
                                                    CLK1_PSI_group %in% c("High CLK1 PSI", "Low CLK1 PSI")) %>%
                                      dplyr::mutate(plot_group = fct_relevel(plot_group,
                                                                            c("Other high-grade glioma", "Atypical Teratoid Rhabdoid Tumor",
                                                                              "DIPG or DMG", "Ependymoma", "Mesenchymal tumor",
                                                                              "Other CNS embryonal tumor", "Low-grade glioma"))),
                              terms = "extent_of_tumor_resection+age_at_diagnosis_years+plot_group+CLK1_PSI_group",
                               file.path(results_dir, "cox_EFS_additive_terms_subtype_cluster_clk1_psi_group.RDS"),
                               "multivariate",
                               years_col = "EFS_years",
                               status_col = "EFS_status")
Warning: There was 1 warning in `dplyr::mutate()`.
ℹ In argument: `plot_group = fct_relevel(...)`.
Caused by warning:
! 4 unknown levels in `f`: Atypical Teratoid Rhabdoid Tumor, DIPG or DMG, Mesenchymal tumor, and Other CNS embryonal
tumor
forest_c7_clk1_efs <- plotForest(readRDS(file.path(results_dir, "cox_EFS_additive_terms_subtype_cluster_clk1_psi_group.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

ggsave(file.path(plot_dir, "forest_add_EFS_cluster7_histology_resection_clk1_psi_group.pdf"),
       forest_c7_clk1_efs,
       width = 9, height = 4, units = "in",
       device = "pdf")

add_model_c7_os <- fit_save_model(cluster7_df %>% 
                                    dplyr::filter(!extent_of_tumor_resection %in% c("Not Reported", "Unavailable")) %>%
                                    dplyr::mutate(plot_group = fct_relevel(plot_group,
                                                                            c("Other high-grade glioma", "Atypical Teratoid Rhabdoid Tumor",
                                                                              "DIPG or DMG", "Ependymoma", "Mesenchymal tumor",
                                                                              "Other CNS embryonal tumor", "Low-grade glioma"))),
                              terms = "extent_of_tumor_resection+age_at_diagnosis_years+plot_group+CLK1_PSI_group",
                               file.path(results_dir, "cox_OS_additive_terms_subtype_cluster_clk1_psi_group.RDS"),
                               "multivariate",
                               years_col = "OS_years",
                               status_col = "OS_status")
Warning: There was 1 warning in `dplyr::mutate()`.
ℹ In argument: `plot_group = fct_relevel(...)`.
Caused by warning:
! 3 unknown levels in `f`: Atypical Teratoid Rhabdoid Tumor, DIPG or DMG, and Mesenchymal tumor
Warning in coxph.fit(X, Y, istrat, offset, init, control, weights = weights, :
Loglik converged before variable 4,6,9 ; coefficient may be infinite.
forest_c7_clk1_os <- plotForest(readRDS(file.path(results_dir, "cox_OS_additive_terms_subtype_cluster_clk1_psi_group.RDS")))
`height` was translated to `width`.
Warning: Removed 3 rows containing missing values or values outside the scale
range (`geom_text()`).

ggsave(file.path(plot_dir, "forest_add_OS_cluster7_histology_resection_clk1_psi_group.pdf"),
       forest_c7_clk1_os,
       width = 9, height = 4, units = "in",
       device = "pdf")

Assess EFS and OS by CLK1 ex 4 TPM in multivariate models and generate forest plots

add_model_c7_efs <- fit_save_model(cluster7_df %>% 
                                      dplyr::filter(extent_of_tumor_resection != "Unavailable") %>%
                                      dplyr::mutate(plot_group = fct_relevel(plot_group,
                                                                            c("Other high-grade glioma", "Atypical Teratoid Rhabdoid Tumor",
                                                                              "DIPG or DMG", "Ependymoma", "Mesenchymal tumor",
                                                                              "Other CNS embryonal tumor", "Low-grade glioma"))),
                              terms = "extent_of_tumor_resection+age_at_diagnosis_years+plot_group+CLK1_Ex4_TPM",
                               file.path(results_dir, "cox_EFS_additive_terms_subtype_cluster_clk1_tpm.RDS"),
                               "multivariate",
                               years_col = "EFS_years",
                               status_col = "EFS_status")
Warning: There was 1 warning in `dplyr::mutate()`.
ℹ In argument: `plot_group = fct_relevel(...)`.
Caused by warning:
! 3 unknown levels in `f`: Atypical Teratoid Rhabdoid Tumor, DIPG or DMG, and Mesenchymal tumor
forest_c7_clk1_efs <- plotForest(readRDS(file.path(results_dir, "cox_EFS_additive_terms_subtype_cluster_clk1_tpm.RDS")))
`height` was translated to `width`.
Warning: Removed 2 rows containing missing values or values outside the scale
range (`geom_text()`).

ggsave(file.path(plot_dir, "forest_add_EFS_cluster7_histology_resection_clk1_tpm.pdf"),
       forest_c7_clk1_efs,
       width = 9, height = 4, units = "in",
       device = "pdf")

add_model_c7_os <- fit_save_model(cluster7_df %>% 
                                    dplyr::filter(!extent_of_tumor_resection %in% c("Not Reported", "Unavailable")) %>%
                                    dplyr::mutate(plot_group = fct_relevel(plot_group,
                                                                            c("Other high-grade glioma", "Atypical Teratoid Rhabdoid Tumor",
                                                                              "DIPG or DMG", "Ependymoma", "Mesenchymal tumor",
                                                                              "Other CNS embryonal tumor", "Low-grade glioma"))),
                              terms = "extent_of_tumor_resection+age_at_diagnosis_years+plot_group+CLK1_Ex4_TPM",
                               file.path(results_dir, "cox_OS_additive_terms_subtype_cluster_clk1_tpm.RDS"),
                               "multivariate",
                               years_col = "OS_years",
                               status_col = "OS_status")
Warning: There was 1 warning in `dplyr::mutate()`.
ℹ In argument: `plot_group = fct_relevel(...)`.
Caused by warning:
! 3 unknown levels in `f`: Atypical Teratoid Rhabdoid Tumor, DIPG or DMG, and Mesenchymal tumor
Warning in coxph.fit(X, Y, istrat, offset, init, control, weights = weights, :
Loglik converged before variable 4,6,9 ; coefficient may be infinite.
forest_c7_clk1_os <- plotForest(readRDS(file.path(results_dir, "cox_OS_additive_terms_subtype_cluster_clk1_tpm.RDS")))
`height` was translated to `width`.
Warning: Removed 2 rows containing missing values or values outside the scale
range (`geom_text()`).

ggsave(file.path(plot_dir, "forest_add_OS_cluster7_histology_resection_clk1_tpm.pdf"),
       forest_c7_clk1_os,
       width = 9, height = 4, units = "in",
       device = "pdf")

Assess EFS and OS by CLK1 ex 4 PSI in multivariate models and generate forest plots

add_model_c7_efs <- fit_save_model(cluster7_df %>% 
                                      dplyr::filter(extent_of_tumor_resection != "Unavailable") %>%
                                      dplyr::mutate(plot_group = fct_relevel(plot_group,
                                                                            c("Other high-grade glioma", "Atypical Teratoid Rhabdoid Tumor",
                                                                              "DIPG or DMG", "Ependymoma", "Mesenchymal tumor",
                                                                              "Other CNS embryonal tumor", "Low-grade glioma"))),
                              terms = "extent_of_tumor_resection+age_at_diagnosis_years+plot_group+CLK1_ex4_PSI",
                               file.path(results_dir, "cox_EFS_additive_terms_subtype_cluster_clk1_psi.RDS"),
                               "multivariate",
                               years_col = "EFS_years",
                               status_col = "EFS_status")
Warning: There was 1 warning in `dplyr::mutate()`.
ℹ In argument: `plot_group = fct_relevel(...)`.
Caused by warning:
! 3 unknown levels in `f`: Atypical Teratoid Rhabdoid Tumor, DIPG or DMG, and Mesenchymal tumor
forest_c7_clk1_efs <- plotForest(readRDS(file.path(results_dir, "cox_EFS_additive_terms_subtype_cluster_clk1_psi.RDS")))
`height` was translated to `width`.
Warning: Removed 2 rows containing missing values or values outside the scale
range (`geom_text()`).

ggsave(file.path(plot_dir, "forest_add_EFS_cluster7_histology_resection_clk1_psi.pdf"),
       forest_c7_clk1_efs,
       width = 9, height = 4, units = "in",
       device = "pdf")

add_model_c7_os <- fit_save_model(cluster7_df %>% 
                                    dplyr::filter(!extent_of_tumor_resection %in% c("Not Reported", "Unavailable")) %>%
                                    dplyr::mutate(plot_group = fct_relevel(plot_group,
                                                                            c("Other high-grade glioma", "Atypical Teratoid Rhabdoid Tumor",
                                                                              "DIPG or DMG", "Ependymoma", "Mesenchymal tumor",
                                                                              "Other CNS embryonal tumor", "Low-grade glioma"))),
                              terms = "extent_of_tumor_resection+age_at_diagnosis_years+plot_group+CLK1_ex4_PSI",
                               file.path(results_dir, "cox_OS_additive_terms_subtype_cluster_clk1_psi.RDS"),
                               "multivariate",
                               years_col = "OS_years",
                               status_col = "OS_status")
Warning: There was 1 warning in `dplyr::mutate()`.
ℹ In argument: `plot_group = fct_relevel(...)`.
Caused by warning:
! 3 unknown levels in `f`: Atypical Teratoid Rhabdoid Tumor, DIPG or DMG, and Mesenchymal tumor
Warning in coxph.fit(X, Y, istrat, offset, init, control, weights = weights, :
Loglik converged before variable 4,6,9 ; coefficient may be infinite.
forest_c7_clk1_os <- plotForest(readRDS(file.path(results_dir, "cox_OS_additive_terms_subtype_cluster_clk1_psi.RDS")))
`height` was translated to `width`.
Warning: Removed 2 rows containing missing values or values outside the scale
range (`geom_text()`).

ggsave(file.path(plot_dir, "forest_add_OS_cluster7_histology_resection_clk1_psi.pdf"),
       forest_c7_clk1_os,
       width = 9, height = 4, units = "in",
       device = "pdf")

Print session info

sessionInfo()
R version 4.4.0 (2024-04-24)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 22.04.4 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so;  LAPACK version 3.10.0

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

time zone: Etc/UTC
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] gtools_3.9.5    survminer_0.4.9 patchwork_1.2.0 ggpubr_0.6.0   
 [5] survival_3.7-0  lubridate_1.9.4 forcats_1.0.1   stringr_1.6.0  
 [9] dplyr_1.1.4     purrr_1.2.0     readr_2.1.6     tidyr_1.3.1    
[13] tibble_3.3.0    ggplot2_4.0.1   tidyverse_2.0.0

loaded via a namespace (and not attached):
 [1] gtable_0.3.6       xfun_0.54          bslib_0.9.0        rstatix_0.7.2     
 [5] lattice_0.22-7     tzdb_0.5.0         vctrs_0.6.5        tools_4.4.0       
 [9] generics_0.1.4     parallel_4.4.0     pkgconfig_2.0.3    Matrix_1.7-4      
[13] data.table_1.17.8  RColorBrewer_1.1-3 S7_0.2.1           lifecycle_1.0.4   
[17] compiler_4.4.0     farver_2.1.2       textshaping_1.0.4  carData_3.0-5     
[21] colorblindr_0.1.0  htmltools_0.5.8.1  sass_0.4.10        yaml_2.3.10       
[25] crayon_1.5.3       pillar_1.11.1      car_3.1-2          jquerylib_0.1.4   
[29] cachem_1.1.0       abind_1.4-5        km.ci_0.5-6        commonmark_2.0.0  
[33] tidyselect_1.2.1   digest_0.6.39      stringi_1.8.7      labeling_0.4.3    
[37] splines_4.4.0      cowplot_1.1.3      rprojroot_2.1.1    fastmap_1.2.0     
[41] grid_4.4.0         colorspace_2.1-2   cli_3.6.5          magrittr_2.0.4    
[45] broom_1.0.10       withr_3.0.2        scales_1.4.0       backports_1.5.0   
[49] bit64_4.6.0-1      timechange_0.3.0   rmarkdown_2.30     ggtext_0.1.2      
[53] bit_4.6.0          gridExtra_2.3      ggsignif_0.6.4     ragg_1.5.0        
[57] zoo_1.8-12         hms_1.1.4          evaluate_1.0.5     knitr_1.50        
[61] KMsurv_0.1-5       markdown_1.13      survMisc_0.5.6     rlang_1.1.6       
[65] Rcpp_1.1.0         gridtext_0.1.5     xtable_1.8-4       glue_1.8.0        
[69] xml2_1.5.0         vroom_1.6.6        jsonlite_2.0.0     R6_2.6.1          
[73] systemfonts_1.3.1 
LS0tCnRpdGxlOiAiUnVuIHNwbGljaW5nIGNsdXN0ZXIgYXNzaWdubWVudCwgc3BsaWNpbmcgYnVyZGVuLCBnc3ZhLCBDTEsxIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQphdXRob3I6IFJ5YW4gQ29yYmV0dCwgYWRhcHRlZCBieSBKbyBMeW5uZSBSb2tpdGEgZm9yIENMSzEKZGF0ZTogMjAyNApwYXJhbXM6CiAgcGxvdF9jaTogVFJVRQotLS0KCioqUHVycG9zZToqKiAKClJ1bnMgc3Vydml2YWwgYW5hbHlzaXMgbW9kZWxzIHVzaW5nIHNwbGljaW5nIGNsdXN0ZXIgYXNzaWdubWVudCBhbmQgMSkgc2luZ2xlIGV4b24gc3BsaWNpbmcgYnVyZGVuIGluZGV4IChTQkkpIDIpIEtFR0cgU3BsaWNlb3NvbWUgR1NWQSBzY29yZXMgb3IgMykgQ0xLMSBleG9uIDQgVFBNIGFzIGEgcHJlZGljdG9yCgojIyBVc2FnZSAKClVzZXMgYSB3cmFwcGVyIGZ1bmN0aW9uIChgc3Vydml2YWxfYW5hbHlzaXNgKSBmcm9tIHV0aWxzIGZvbGRlci4gCgojIyBTZXR1cAoKIyMjIyBQYWNrYWdlcyBhbmQgZnVuY3Rpb25zCgpMb2FkIHBhY2thZ2VzLCBzZXQgZGlyZWN0b3J5IHBhdGhzIGFuZCBjYWxsIHNldHVwIHNjcmlwdAoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHN1cnZpdmFsKQpsaWJyYXJ5KGdncHVicikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHBhdGNod29yaykKCnJvb3RfZGlyIDwtIHJwcm9qcm9vdDo6ZmluZF9yb290KHJwcm9qcm9vdDo6aGFzX2RpcigiLmdpdCIpKQoKZGF0YV9kaXIgPC0gZmlsZS5wYXRoKHJvb3RfZGlyLCAiZGF0YSIpCmFuYWx5c2lzX2RpciA8LSBmaWxlLnBhdGgocm9vdF9kaXIsICJhbmFseXNlcyIsICJzdXJ2aXZhbCIpCmlucHV0X2RpciA8LSBmaWxlLnBhdGgoYW5hbHlzaXNfZGlyLCAicmVzdWx0cyIpCnJlc3VsdHNfZGlyIDwtIGZpbGUucGF0aChhbmFseXNpc19kaXIsICJyZXN1bHRzIikKcGxvdF9kaXIgPC0gZmlsZS5wYXRoKGFuYWx5c2lzX2RpciwgInBsb3RzIikKCiMgSWYgdGhlIGlucHV0IGFuZCByZXN1bHRzIGRpcmVjdG9yaWVzIGRvIG5vdCBleGlzdCwgY3JlYXRlIGl0CmlmICghZGlyLmV4aXN0cyhyZXN1bHRzX2RpcikpIHsKICBkaXIuY3JlYXRlKHJlc3VsdHNfZGlyLCByZWN1cnNpdmUgPSBUUlVFKQp9Cgpzb3VyY2UoZmlsZS5wYXRoKGFuYWx5c2lzX2RpciwgInV0aWwiLCAic3Vydml2YWxfbW9kZWxzLlIiKSkKYGBgCgpTZXQgbWV0YWRhdGEgYW5kIGNsdXN0ZXIgYXNzaWdubWVudCBmaWxlIHBhdGhzCgpgYGB7ciBzZXQgcGF0aHN9Cm1ldGFkYXRhX2ZpbGUgPC0gZmlsZS5wYXRoKGlucHV0X2RpciwgInNwbGljaW5nX2luZGljZXNfd2l0aF9zdXJ2aXZhbC50c3YiKQoKY2x1c3Rlcl9maWxlIDwtIGZpbGUucGF0aChyb290X2RpciwgImFuYWx5c2VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2FtcGxlLXBzaS1jbHVzdGVyaW5nIiwgInJlc3VsdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzYW1wbGUtY2x1c3Rlci1tZXRhZGF0YS10b3AtNTAwMC1ldmVudHMtc3RyYW5kZWQudHN2IikKCmtlZ2dfc2NvcmVzX3N0cmFuZGVkX2ZpbGUgPC0gZmlsZS5wYXRoKHJvb3RfZGlyLCAiYW5hbHlzZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJzYW1wbGUtcHNpLWNsdXN0ZXJpbmciLCAicmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgImdzdmFfb3V0cHV0X3N0cmFuZGVkLnRzdiIpCgp0cG1fZmlsZSA8LSBmaWxlLnBhdGgoZGF0YV9kaXIsICJybmEtaXNvZm9ybS1leHByZXNzaW9uLXJzZW0tdHBtLnJkcyIpCmNsazFfcHNpX2ZpbGUgPC0gZmlsZS5wYXRoKHJvb3RfZGlyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgImFuYWx5c2VzIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJDTEsxLXNwbGljaW5nX2NvcnJlbGF0aW9ucyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAicmVzdWx0cyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAiY2xrMS1leG9uNC1wc2kudHN2IikKYGBgCgpXcmFuZ2xlIGRhdGEgCkFkZCBjbHVzdGVyIGFzc2lnbm1lbnQgYW5kIHNwbGljZW9zb21lIGdzdmEgc2NvcmVzIHRvIGBtZXRhZGF0YWAgYW5kIGRlZmluZSBjb2x1bW4gYGxnZ19ncm91cGAgKExHRyBvciBub25fTEdHKQoKYGBge3J9Cm1ldGFkYXRhIDwtIHJlYWRfdHN2KG1ldGFkYXRhX2ZpbGUpCgpjbHVzdGVycyA8LSByZWFkX3RzdihjbHVzdGVyX2ZpbGUpICU+JQogIGRwbHlyOjpyZW5hbWUoS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCA9IHNhbXBsZV9pZCkKCmNsazFfcHNpIDwtIHJlYWRfdHN2KGNsazFfcHNpX2ZpbGUpICU+JQogIGRwbHlyOjpyZW5hbWUoQ0xLMV9leDRfUFNJID0gUFNJKSAlPiUKICBzZWxlY3QoLXBsb3RfZ3JvdXApCgpnc3ZhX3Njb3JlcyA8LSByZWFkX3RzdihrZWdnX3Njb3Jlc19zdHJhbmRlZF9maWxlKSAlPiUKICBkcGx5cjo6ZmlsdGVyKGdlbmVzZXQgPT0gIktFR0dfU1BMSUNFT1NPTUUiKSAlPiUKICBkcGx5cjo6cmVuYW1lKHNwbGljZW9zb21lX2dzdmFfc2NvcmUgPSBzY29yZSkKCmFsbF9jbGs0X3RyYW5zY3JfY291bnRzIDwtIHJlYWRSRFModHBtX2ZpbGUpICU+JQogIGZpbHRlcihncmVwbCgiXkNMSzEiLCBnZW5lX3N5bWJvbCkpICU+JQogIG11dGF0ZSgKICAgIHRyYW5zY3JpcHRfaWQgPSBjYXNlX3doZW4oCiAgICAgIHRyYW5zY3JpcHRfaWQgJWluJSBjKCJFTlNUMDAwMDAzMjEzNTYuOSIsICJFTlNUMDAwMDA0MzQ4MTMuMyIsICJFTlNUMDAwMDA0MDk0MDMuNiIpIH4gIkV4b24gNCIsCiMgICAgICB0cmFuc2NyaXB0X2lkID09ICJFTlNUMDAwMDAzMjEzNTYuOSIgfiAiRXhvbiA0IiwKICAgICAgVFJVRSB+ICJPdGhlciIKICAgICkKICApICU+JQogIGdyb3VwX2J5KHRyYW5zY3JpcHRfaWQpICU+JQogIHN1bW1hcmlzZShhY3Jvc3Moc3RhcnRzX3dpdGgoIkJTIiksIHN1bSwgbmEucm0gPSBUUlVFKSkgJT4lCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtdHJhbnNjcmlwdF9pZCwgbmFtZXNfdG8gPSAiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsIHZhbHVlc190byA9ICJDTEsxX0V4NF9UUE0iKSAlPiUKICBmaWx0ZXIodHJhbnNjcmlwdF9pZCA9PSAiRXhvbiA0IikgJT4lCiAgaW5uZXJfam9pbihjbHVzdGVycywgYnkgPSAiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIpICU+JQogIGxlZnRfam9pbihjbGsxX3BzaSkKCiMgaG93IG1hbnkgY2x1c3RlcnM/Cm5fY2x1c3QgPC0gbGVuZ3RoKHVuaXF1ZShjbHVzdGVycyRjbHVzdGVyKSkKCm1ldGFkYXRhIDwtIG1ldGFkYXRhICU+JQogIHJpZ2h0X2pvaW4oYWxsX2NsazRfdHJhbnNjcl9jb3VudHMgJT4lIGRwbHlyOjpzZWxlY3QoS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2x1c3RlciwgQ0xLMV9FeDRfVFBNLCBDTEsxX2V4NF9QU0kpKSAlPiUKICBsZWZ0X2pvaW4oZ3N2YV9zY29yZXMgJT4lIGRwbHlyOjpzZWxlY3Qoc2FtcGxlX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlKSwKICAgICAgICAgICAgYnkgPSBjKCJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIiA9ICJzYW1wbGVfaWQiKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoY2x1c3RlciA9IGdsdWU6OmdsdWUoIkNsdXN0ZXIge2NsdXN0ZXJ9IikpICU+JQogIGRwbHlyOjptdXRhdGUoY2x1c3RlciA9IGZjdF9yZWxldmVsKGNsdXN0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFzdGUwKCJDbHVzdGVyICIsIDE6bl9jbHVzdCkpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGxnZ19ncm91cCA9IGNhc2Vfd2hlbigKICAgIHBsb3RfZ3JvdXAgPT0gIkxvdy1ncmFkZSBnbGlvbWEiIH4gIkxHRyIsCiAgICBUUlVFIH4gIm5vbi1MR0ciCiAgKSkgJT4lCiAgZHBseXI6Om11dGF0ZShTQkkgPSBTSV9Ub3RhbCAqIDEwKSAlPiUKICBkcGx5cjo6bXV0YXRlKGFnZV9hdF9kaWFnbm9zaXNfeWVhcnMgPSBhZ2VfYXRfZGlhZ25vc2lzX2RheXMvMzY1LjI1KQpgYGAKCkdlbmVyYXRlIGNveHBoIG1vZGVscyBpbmNsdWRpbmcgZXh0ZW50IG9mIHR1bW9yIHJlc2VjdGlvbiwgbGdnIGdyb3VwLCBjbHVzdGVyIGFzc2lnbm1lbnQsIFNCSSwgYW5kIENMSzEgZXhvbiA0IFRQTSBhcyBjb3ZhcmlhdGVzCgpgYGB7cn0KYWRkX21vZGVsX29zIDwtIGZpdF9zYXZlX21vZGVsKG1ldGFkYXRhWyFtZXRhZGF0YSRleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICVpbiUgYygiTm90IFJlcG9ydGVkIiwgIlVuYXZhaWxhYmxlIiksXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbitsZ2dfZ3JvdXArY2x1c3RlcithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK1NCSStDTEsxX0V4NF9UUE0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X09TX2FkZGl0aXZlX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9TQklfQ0xLMV9FeDRfVFBNLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiT1NfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJPU19zdGF0dXMiKQoKZm9yZXN0X29zIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfT1NfYWRkaXRpdmVfdGVybXNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyX1NCSV9DTEsxX0V4NF9UUE0uUkRTIikpKQoKZm9yZXN0X29zCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAiZm9yZXN0X2FkZF9PU19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfYXNzaWdubWVudF9TQklfQ0xLMV9FeDRfVFBNLnBkZiIpLAogICAgICAgZm9yZXN0X29zLAogICAgICAgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNiwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCgphZGRfbW9kZWxfZWZzIDwtIGZpdF9zYXZlX21vZGVsKG1ldGFkYXRhWyFtZXRhZGF0YSRleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICVpbiUgYygiTm90IFJlcG9ydGVkIiwgIlVuYXZhaWxhYmxlIiksXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbitsZ2dfZ3JvdXArY2x1c3RlcithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK1NCSStDTEsxX0V4NF9UUE0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X0VGU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfU0JJX0NMSzFfRXg0X1RQTS5SRFMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXZhcmlhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcnNfY29sID0gIkVGU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIkVGU19zdGF0dXMiKQoKZm9yZXN0X2VmcyA8LSBwbG90Rm9yZXN0KHJlYWRSRFMoZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X0VGU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfU0JJX0NMSzFfRXg0X1RQTS5SRFMiKSkpCgpmb3Jlc3RfZWZzCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAiZm9yZXN0X2FkZF9FRlNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyX2Fzc2lnbm1lbnRfU0JJX0NMSzFfRXg0X1RQTS5wZGYiKSwKICAgICAgIGZvcmVzdF9lZnMsCiAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKYGBgCnJlcGVhdCBhbmFseXNpcyB3aXRoIENMSzEgZXhvbiA0IFRQTSBhbG9uZQoKYGBge3J9CmFkZF9tb2RlbF9vcyA8LSBmaXRfc2F2ZV9tb2RlbChtZXRhZGF0YVshbWV0YWRhdGEkZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbiAlaW4lIGMoIk5vdCBSZXBvcnRlZCIsICJVbmF2YWlsYWJsZSIpLF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rbGdnX2dyb3VwK2NsdXN0ZXIrYWdlX2F0X2RpYWdub3Npc195ZWFycytDTEsxX0V4NF9UUE0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X09TX2FkZGl0aXZlX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9DTEsxX0V4NF9UUE0uUkRTIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJPU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIk9TX3N0YXR1cyIpCgpmb3Jlc3Rfb3MgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9PU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfQ0xLMV9FeDRfVFBNLlJEUyIpKSkKCmZvcmVzdF9vcwoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfT1NfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyX2Fzc2lnbm1lbnRfQ0xLMV9FeDRfVFBNLnBkZiIpLAogICAgICAgZm9yZXN0X29zLAogICAgICAgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNiwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCgoKYWRkX21vZGVsX2VmcyA8LSBmaXRfc2F2ZV9tb2RlbChtZXRhZGF0YVshbWV0YWRhdGEkZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbiAlaW4lIGMoIk5vdCBSZXBvcnRlZCIsICJVbmF2YWlsYWJsZSIpLF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rbGdnX2dyb3VwK2NsdXN0ZXIrYWdlX2F0X2RpYWdub3Npc195ZWFycytDTEsxX0V4NF9UUE0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X0VGU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfQ0xLMV9FeDRfVFBNLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiRUZTX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIpCgpmb3Jlc3RfZWZzIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfRUZTX2FkZGl0aXZlX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9DTEsxX0V4NF9UUE0uUkRTIikpKQoKZm9yZXN0X2VmcwoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfRUZTX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9hc3NpZ25tZW50X0NMSzFfRXg0X1RQTS5wZGYiKSwKICAgICAgIGZvcmVzdF9lZnMsCiAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKCgpgYGAKCgpyZXBlYXQgYW5hbHlzaXMgd2l0aCBDTEsxIGV4b24gNCBQU0kKCmBgYHtyfQphZGRfbW9kZWxfb3MgPC0gZml0X3NhdmVfbW9kZWwobWV0YWRhdGFbIW1ldGFkYXRhJGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtcyA9ICJleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uK2xnZ19ncm91cCtjbHVzdGVyK2FnZV9hdF9kaWFnbm9zaXNfeWVhcnMrQ0xLMV9leDRfUFNJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9PU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfQ0xLMV9leDRfUFNJLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiT1NfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJPU19zdGF0dXMiKQoKZm9yZXN0X29zIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfT1NfYWRkaXRpdmVfdGVybXNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyX0NMSzFfZXg0X1BTSS5SRFMiKSkpCgpmb3Jlc3Rfb3MKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX09TX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9hc3NpZ25tZW50X0NMSzFfZXg0X1BTSS5wZGYiKSwKICAgICAgIGZvcmVzdF9vcywKICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDYsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQoKYWRkX21vZGVsX2VmcyA8LSBmaXRfc2F2ZV9tb2RlbChtZXRhZGF0YVshbWV0YWRhdGEkZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbiAlaW4lIGMoIk5vdCBSZXBvcnRlZCIsICJVbmF2YWlsYWJsZSIpLF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rbGdnX2dyb3VwK2NsdXN0ZXIrYWdlX2F0X2RpYWdub3Npc195ZWFycytDTEsxX2V4NF9QU0kiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X0VGU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfQ0xLMV9leDRfUFNJLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiRUZTX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIpCgpmb3Jlc3RfZWZzIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfRUZTX2FkZGl0aXZlX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9DTEsxX2V4NF9QU0kuUkRTIikpKQoKZm9yZXN0X2VmcwoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfRUZTX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9hc3NpZ25tZW50X0NMSzFfZXg0X1BTSS5wZGYiKSwKICAgICAgIGZvcmVzdF9lZnMsCiAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKYGBgCgoKSW50ZXJhY3Rpb24gd2l0aCBHU1ZBLCBTQkksIENMSzEKCmBgYHtyIEludGVyYWN0aW9uIG1vZGVscyB3aXRoIEdTVkEsIFNCSSwgQ0xLMX0KbW9kZWxzIDwtIGMoInNwbGljZW9zb21lX2dzdmFfc2NvcmUiLCAiU0JJIiwgIkNMSzFfRXg0X1RQTSIsICJDTEsxX2V4NF9QU0kiKQojIGJ5IGNsdXN0ZXIKZm9yIChlYWNoIGluIG1vZGVscykgewogIGludF9tb2RlbF9lZnMgPC0gZml0X3NhdmVfbW9kZWwobWV0YWRhdGFbIW1ldGFkYXRhJGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gcGFzdGUwKCJleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uK2xnZ19ncm91cCtjbHVzdGVyKiIsIGVhY2gsICIrYWdlX2F0X2RpYWdub3Npc195ZWFycyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsIHBhc3RlMCgiY294X0VGU19pbnRlcmFjdGlvbl90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfIiwgZWFjaCwgIi5SRFMiKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXZhcmlhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiRUZTX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJFRlNfc3RhdHVzIikKICAKICBpbnRfZm9yZXN0X2VmcyA8LSBwbG90Rm9yZXN0KHJlYWRSRFMoZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCBwYXN0ZTAoImNveF9FRlNfaW50ZXJhY3Rpb25fdGVybXNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyXyIsIGVhY2gsICIuUkRTIikpKSkKICAKICBpbnRfZm9yZXN0X2VmcwogIAogIGdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsIHBhc3RlMCgiZm9yZXN0X2ludF9FRlNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyX2Fzc2lnbm1lbnRfIiwgZWFjaCwgIi5wZGYiKSksCiAgICAgICAgIGludF9mb3Jlc3RfZWZzLAogICAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsCiAgICAgICAgIGRldmljZSA9ICJwZGYiKQoKICBpbnRfbW9kZWxfb3MgPC0gZml0X3NhdmVfbW9kZWwobWV0YWRhdGFbIW1ldGFkYXRhJGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gcGFzdGUwKCJleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uK2xnZ19ncm91cCtjbHVzdGVyKiIsIGVhY2gsICIrYWdlX2F0X2RpYWdub3Npc195ZWFycyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsIHBhc3RlMCgiY294X09TX2ludGVyYWN0aW9uX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl8iLCBlYWNoLCAiLlJEUyIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJPU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiT1Nfc3RhdHVzIikKICAKICBpbnRfZm9yZXN0X29zIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsIHBhc3RlMCgiY294X09TX2ludGVyYWN0aW9uX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl8iLCBlYWNoLCAiLlJEUyIpKSkpCiAgCiAgaW50X2ZvcmVzdF9vcwogIAogIGdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsIHBhc3RlMCgiZm9yZXN0X2ludF9PU19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfYXNzaWdubWVudF8iLCBlYWNoLCAiLnBkZiIpKSwKICAgICAgICAgaW50X2ZvcmVzdF9vcywKICAgICAgICAgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNiwgdW5pdHMgPSAiaW4iLAogICAgICAgICBkZXZpY2UgPSAicGRmIikKfQoKIyMgY2xrMSB4IGFnZQogIGludF9tb2RlbF9lZnMgPC0gZml0X3NhdmVfbW9kZWwobWV0YWRhdGFbIW1ldGFkYXRhJGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gcGFzdGUwKCJleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uK2xnZ19ncm91cCtjbHVzdGVyK0NMSzFfRXg0X1RQTSphZ2VfYXRfZGlhZ25vc2lzX3llYXJzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgcGFzdGUwKCJjb3hfRUZTX2ludGVyYWN0aW9uX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9DTEsxX0V4NF9UUE1fYWdlLlJEUyIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJFRlNfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIkVGU19zdGF0dXMiKQogIAogIGludF9mb3Jlc3RfZWZzIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsIHBhc3RlMCgiY294X0VGU19pbnRlcmFjdGlvbl90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfQ0xLMV9FeDRfVFBNX2FnZS5SRFMiKSkpKQogIAogIGludF9mb3Jlc3RfZWZzCiAgCiAgZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgcGFzdGUwKCJmb3Jlc3RfaW50X0VGU19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfY2xrMV9hZ2UucGRmIikpLAogICAgICAgICBpbnRfZm9yZXN0X2VmcywKICAgICAgICAgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNiwgdW5pdHMgPSAiaW4iLAogICAgICAgICBkZXZpY2UgPSAicGRmIikKCiAgaW50X21vZGVsX29zIDwtIGZpdF9zYXZlX21vZGVsKG1ldGFkYXRhWyFtZXRhZGF0YSRleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICVpbiUgYygiTm90IFJlcG9ydGVkIiwgIlVuYXZhaWxhYmxlIiksXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtcyA9IHBhc3RlMCgiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbitsZ2dfZ3JvdXArY2x1c3RlcitDTEsxX0V4NF9UUE0qYWdlX2F0X2RpYWdub3Npc195ZWFycyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsIHBhc3RlMCgiY294X09TX2ludGVyYWN0aW9uX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9jbGsxX2FnZS5SRFMiKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXZhcmlhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiT1NfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIk9TX3N0YXR1cyIpCiAgCiAgaW50X2ZvcmVzdF9vcyA8LSBwbG90Rm9yZXN0KHJlYWRSRFMoZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCBwYXN0ZTAoImNveF9PU19pbnRlcmFjdGlvbl90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfY2xrMV9hZ2UuUkRTIikpKSkKICAKICBpbnRfZm9yZXN0X29zCiAgCiAgZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgcGFzdGUwKCJmb3Jlc3RfaW50X09TX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9jbGsxX2FnZS5wZGYiKSksCiAgICAgICAgIGludF9mb3Jlc3Rfb3MsCiAgICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDYsIHVuaXRzID0gImluIiwKICAgICAgICAgZGV2aWNlID0gInBkZiIpCgptb2RlbHMyIDwtIGMoIlNCSSIsICJDTEsxX0V4NF9UUE0iKQpmb3IgKGVhY2ggaW4gbW9kZWxzMikgewogICMjIyMgYnkgc3BsaWNlb3NvbWVfZ3N2YV9zY29yZQogIGludF9tb2RlbF9lZnMgPC0gZml0X3NhdmVfbW9kZWwobWV0YWRhdGFbIW1ldGFkYXRhJGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gcGFzdGUwKCJleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uK2xnZ19ncm91cCtjbHVzdGVyK3NwbGljZW9zb21lX2dzdmFfc2NvcmUqIiwgZWFjaCwgIithZ2VfYXRfZGlhZ25vc2lzX3llYXJzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgcGFzdGUwKCJjb3hfRUZTX2ludGVyYWN0aW9uX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9zcGxpY2Vvc29tZV9nc3ZhX3Njb3JlXyIsIGVhY2gsICIuUkRTIikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcnNfY29sID0gIkVGU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIpCiAgCiAgaW50X2ZvcmVzdF9lZnMgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgcGFzdGUwKCJjb3hfRUZTX2ludGVyYWN0aW9uX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9zcGxpY2Vvc29tZV9nc3ZhX3Njb3JlXyIsIGVhY2gsICIuUkRTIikpKSkKICAKICBpbnRfZm9yZXN0X2VmcwogIAogIGdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsIHBhc3RlMCgiY294X0VGU19pbnRlcmFjdGlvbl90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfc3BsaWNlb3NvbWVfZ3N2YV9zY29yZV8iLCBlYWNoLCAiLnBkZiIpKSwKICAgICAgICAgaW50X2ZvcmVzdF9lZnMsCiAgICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDYsIHVuaXRzID0gImluIiwKICAgICAgICAgZGV2aWNlID0gInBkZiIpCn0KICAKCgphZGRfbW9kZWxfZWZzIDwtIGZpdF9zYXZlX21vZGVsKG1ldGFkYXRhWyFtZXRhZGF0YSRleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICVpbiUgYygiTm90IFJlcG9ydGVkIiwgIlVuYXZhaWxhYmxlIiksXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbitsZ2dfZ3JvdXArY2x1c3RlcithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3NwbGljZW9zb21lX2dzdmFfc2NvcmUrQ0xLMV9FeDRfVFBNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9FRlNfYWRkaXRpdmVfdGVybXNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyX3NwbGljZW9zb21lX3Njb3JlX0NMSzFfRXg0X1RQTS5SRFMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXZhcmlhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcnNfY29sID0gIkVGU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIkVGU19zdGF0dXMiKQoKZm9yZXN0X2VmcyA8LSBwbG90Rm9yZXN0KHJlYWRSRFMoZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X0VGU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfc3BsaWNlb3NvbWVfc2NvcmVfQ0xLMV9FeDRfVFBNLlJEUyIpKSkKCmZvcmVzdF9lZnMKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX0VGU19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfYXNzaWdubWVudF9zcGxpY2Vvc29tZV9zY29yZV9DTEsxX0V4NF9UUE0ucGRmIiksCiAgICAgICBmb3Jlc3RfZWZzLAogICAgICAgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNiwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCgoKYWRkX21vZGVsX29zIDwtIGZpdF9zYXZlX21vZGVsKG1ldGFkYXRhWyFtZXRhZGF0YSRleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICVpbiUgYygiTm90IFJlcG9ydGVkIiwgIlVuYXZhaWxhYmxlIiksXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbitsZ2dfZ3JvdXArY2x1c3RlcithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3NwbGljZW9zb21lX2dzdmFfc2NvcmUrQ0xLMV9FeDRfVFBNIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9PU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfc3BsaWNlb3NvbWVfc2NvcmVfQ0xLMV9FeDRfVFBNLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiRUZTX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIpCgpmb3Jlc3Rfb3MgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9PU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfc3BsaWNlb3NvbWVfc2NvcmVfQ0xLMV9FeDRfVFBNLlJEUyIpKSkKCmZvcmVzdF9vcwoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfT1NfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyX2Fzc2lnbm1lbnRfc3BsaWNlb3NvbWVfc2NvcmVfQ0xLMV9FeDRfVFBNLnBkZiIpLAogICAgICAgZm9yZXN0X2VmcywKICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDYsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQoKCmBgYAoKCgpGaWx0ZXIgZm9yIGNsdXN0ZXIgNwoKYGBge3J9CmNsdXN0ZXI3X2RmIDwtIG1ldGFkYXRhICU+JQogIGRwbHlyOjpmaWx0ZXIoY2x1c3RlciA9PSAiQ2x1c3RlciA3IiwKICAgICAgICAgICAgICAgICFpcy5uYShFRlNfZGF5cykpICU+JQogIGRwbHlyOjptdXRhdGUoQ0xLMV9UUE1fZ3JvdXAgPSBjYXNlX3doZW4oCiAgICAgIENMSzFfRXg0X1RQTSA+IHN1bW1hcnkoQ0xLMV9FeDRfVFBNKVsiM3JkIFF1LiJdIH4gIkhpZ2ggQ0xLMSBUUE0iLAogICAgICBDTEsxX0V4NF9UUE0gPCBzdW1tYXJ5KENMSzFfRXg0X1RQTSlbIjFzdCBRdS4iXSB+ICJMb3cgQ0xLMSBUUE0iLAogICAgICBUUlVFIH4gTkFfY2hhcmFjdGVyXyksCiAgICAgIENMSzFfUFNJX2dyb3VwID0gY2FzZV93aGVuKENMSzFfZXg0X1BTSSA+IHN1bW1hcnkoQ0xLMV9leDRfUFNJKVsiM3JkIFF1LiJdIH4gIkhpZ2ggQ0xLMSBQU0kiLAogICAgICBDTEsxX2V4NF9QU0kgPCBzdW1tYXJ5KENMSzFfZXg0X1BTSSlbIjFzdCBRdS4iXSB+ICJMb3cgQ0xLMSBQU0kiLAogICAgICBUUlVFIH4gTkFfY2hhcmFjdGVyXwogICAgKSkgJT4lCiAgZHBseXI6Om11dGF0ZShDTEsxX1RQTV9ncm91cCA9IGZjdF9yZWxldmVsKENMSzFfVFBNX2dyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiTG93IENMSzEgVFBNIiwgIkhpZ2ggQ0xLMSBUUE0iKSksCiAgICAgICAgICAgICAgICBDTEsxX1BTSV9ncm91cCA9IGZjdF9yZWxldmVsKENMSzFfUFNJX2dyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiTG93IENMSzEgUFNJIiwgIkhpZ2ggQ0xLMSBQU0kiKSkpCmBgYAoKR2VuZXJhdGUgS00gbW9kZWxzIHdpdGggYENMSzFfVFBNX2dyb3VwYCBhcyBjb3ZhcmlhdGUKCmBgYHtyfQojIEdlbmVyYXRlIGthcGxhbiBtZWllciBzdXJ2aXZhbCBtb2RlbHMgZm9yIE9TIGFuZCBFRlMsIGFuZCBzYXZlIG91dHB1dHMKYzdfY2xrX3RwbV9rYXBfb3MgPC0gc3Vydml2YWxfYW5hbHlzaXMoCiAgbWV0YWRhdGEgID0gY2x1c3RlcjdfZGYgJT4lIAogICAgZHBseXI6OmZpbHRlcighaXMubmEoQ0xLMV9UUE1fZ3JvdXApKSwKICBpbmRfdmFyID0gIkNMSzFfVFBNX2dyb3VwIiwKICB0ZXN0ID0gImthcC5tZWllciIsCiAgbWV0YWRhdGFfc2FtcGxlX2NvbCA9ICJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIiwKICBkYXlzX2NvbCA9ICJPU19kYXlzIiwKICBzdGF0dXNfY29sID0gIk9TX3N0YXR1cyIKKQoKcmVhZHI6OndyaXRlX3JkcyhjN19jbGtfdHBtX2thcF9vcywKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJsb2dyYW5rX2NsdXN0ZXI3X09TX2NsazFfdHBtX2dyb3VwLlJEUyIpKQoKYzdfY2xrX3RwbV9rYXBfZWZzIDwtIHN1cnZpdmFsX2FuYWx5c2lzKAogIG1ldGFkYXRhICA9IGNsdXN0ZXI3X2RmICU+JSAKICAgIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKENMSzFfVFBNX2dyb3VwKSksCiAgaW5kX3ZhciA9ICJDTEsxX1RQTV9ncm91cCIsCiAgdGVzdCA9ICJrYXAubWVpZXIiLAogIG1ldGFkYXRhX3NhbXBsZV9jb2wgPSAiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsCiAgZGF5c19jb2wgPSAiRUZTX2RheXMiLAogIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIKKQoKcmVhZHI6OndyaXRlX3JkcyhjN19jbGtfdHBtX2thcF9lZnMsCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAibG9ncmFua19jbHVzdGVyN19FRlNfY2xrMV90cG1fZ3JvdXAuUkRTIikpCmBgYAoKCkdlbmVyYXRlIEtNIG1vZGVscyB3aXRoIGBDTEsxX1BTSV9ncm91cGAgYXMgY292YXJpYXRlCgpgYGB7cn0KIyBHZW5lcmF0ZSBrYXBsYW4gbWVpZXIgc3Vydml2YWwgbW9kZWxzIGZvciBPUyBhbmQgRUZTLCBhbmQgc2F2ZSBvdXRwdXRzCmM3X2Nsa19wc2lfa2FwX29zIDwtIHN1cnZpdmFsX2FuYWx5c2lzKAogIG1ldGFkYXRhICA9IGNsdXN0ZXI3X2RmICU+JSAKICAgIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKENMSzFfUFNJX2dyb3VwKSksCiAgaW5kX3ZhciA9ICJDTEsxX1BTSV9ncm91cCIsCiAgdGVzdCA9ICJrYXAubWVpZXIiLAogIG1ldGFkYXRhX3NhbXBsZV9jb2wgPSAiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsCiAgZGF5c19jb2wgPSAiT1NfZGF5cyIsCiAgc3RhdHVzX2NvbCA9ICJPU19zdGF0dXMiCikKCnJlYWRyOjp3cml0ZV9yZHMoYzdfY2xrX3BzaV9rYXBfb3MsCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAibG9ncmFua19jbHVzdGVyN19PU19jbGsxX3BzaV9ncm91cC5SRFMiKSkKCmM3X2Nsa19wc2lfa2FwX2VmcyA8LSBzdXJ2aXZhbF9hbmFseXNpcygKICBtZXRhZGF0YSAgPSBjbHVzdGVyN19kZiAlPiUgCiAgICBkcGx5cjo6ZmlsdGVyKCFpcy5uYShDTEsxX1BTSV9ncm91cCkpLAogIGluZF92YXIgPSAiQ0xLMV9QU0lfZ3JvdXAiLAogIHRlc3QgPSAia2FwLm1laWVyIiwKICBtZXRhZGF0YV9zYW1wbGVfY29sID0gIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiLAogIGRheXNfY29sID0gIkVGU19kYXlzIiwKICBzdGF0dXNfY29sID0gIkVGU19zdGF0dXMiCikKCnJlYWRyOjp3cml0ZV9yZHMoYzdfY2xrX3BzaV9rYXBfZWZzLAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImxvZ3JhbmtfY2x1c3RlcjdfRUZTX2NsazFfcHNpX2dyb3VwLlJEUyIpKQpgYGAKCkdlbmVyYXRlIGNsdXN0ZXIgNyBLTSBTSV9ncm91cCBwbG90cwoKYGBge3J9CmttX2M3X2Nsa190cG1fb3NfcGxvdCA8LSBwbG90S00obW9kZWwgPSBjN19jbGtfdHBtX2thcF9vcywKICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZSA9ICJDTEsxX1RQTV9ncm91cCIsCiAgICAgICAgICAgICAgICAgICAgY29tYmluZWQgPSBGLCAKICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDbHVzdGVyIDcsIG92ZXJhbGwgc3Vydml2YWwiLAogICAgICAgICAgICAgICAgICAgIHBfcG9zID0gInRvcHJpZ2h0IikKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJrbV9jbHVzdGVyN19PU19jbGsxX3RwbV9ncm91cC5wZGYiKSwKICAgICAgIGttX2M3X2Nsa190cG1fb3NfcGxvdCwKICAgICAgIHdpZHRoID0gOCwgaGVpZ2h0ID0gNSwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCgprbV9jN19jbGsxX3RwbV9lZnNfcGxvdCA8LSBwbG90S00obW9kZWwgPSBjN19jbGtfdHBtX2thcF9lZnMsCiAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUgPSAiQ0xLMV9UUE1fZ3JvdXAiLAogICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkID0gRiwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiQ2x1c3RlciA3LCBldmVudC1mcmVlIHN1cnZpdmFsIiwKICAgICAgICAgICAgICAgICAgICBwX3BvcyA9ICJ0b3ByaWdodCIpCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAia21fY2x1c3RlcjdfRUZTX2NsazFfdHBtX2dyb3VwLnBkZiIpLCAKICAgICAgIGttX2M3X2NsazFfdHBtX2Vmc19wbG90LAogICAgICAgd2lkdGggPSA4LCBoZWlnaHQgPSA1LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKCmttX2M3X2NsazFfcHNpX29zX3Bsb3QgPC0gcGxvdEtNKG1vZGVsID0gYzdfY2xrX3BzaV9rYXBfb3MsCiAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUgPSAiQ0xLMV9QU0lfZ3JvdXAiLAogICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkID0gRiwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiQ2x1c3RlciA3LCBvdmVyYWxsIHN1cnZpdmFsIiwKICAgICAgICAgICAgICAgICAgICBwX3BvcyA9ICJ0b3ByaWdodCIpCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAia21fY2x1c3RlcjdfT1NfY2xrMV9wc2lfZ3JvdXAucGRmIiksCiAgICAgICBrbV9jN19jbGsxX3BzaV9vc19wbG90LAogICAgICAgd2lkdGggPSA4LCBoZWlnaHQgPSA1LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKCmttX2M3X2NsazFfcHNpX2Vmc19wbG90IDwtIHBsb3RLTShtb2RlbCA9IGM3X2Nsa19wc2lfa2FwX2VmcywKICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZSA9ICJDTEsxX1BTSV9ncm91cCIsCiAgICAgICAgICAgICAgICAgICAgY29tYmluZWQgPSBGLCAKICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDbHVzdGVyIDcsIGV2ZW50LWZyZWUgc3Vydml2YWwiLAogICAgICAgICAgICAgICAgICAgIHBfcG9zID0gInRvcHJpZ2h0IikKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJrbV9jbHVzdGVyN19FRlNfY2xrMV9wc2lfZ3JvdXAucGRmIiksIAogICAgICAga21fYzdfY2xrMV9wc2lfZWZzX3Bsb3QsCiAgICAgICB3aWR0aCA9IDgsIGhlaWdodCA9IDUsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQoKYGBgCgpBc3Nlc3MgRUZTIGFuZCBPUyBieSBDTEsxIFRQTSBncm91cCBpbiBtdWx0aXZhcmlhdGUgbW9kZWxzIGFuZCBnZW5lcmF0ZSBmb3Jlc3QgcGxvdHMKCmBgYHtyfQphZGRfbW9kZWxfYzdfZWZzIDwtIGZpdF9zYXZlX21vZGVsKGNsdXN0ZXI3X2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gIT0gIlVuYXZhaWxhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENMSzFfVFBNX2dyb3VwICVpbiUgYygiSGlnaCBDTEsxIFRQTSIsICJMb3cgQ0xLMSBUUE0iKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShwbG90X2dyb3VwID0gZmN0X3JlbGV2ZWwocGxvdF9ncm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIk90aGVyIGhpZ2gtZ3JhZGUgZ2xpb21hIiwgIkF0eXBpY2FsIFRlcmF0b2lkIFJoYWJkb2lkIFR1bW9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRJUEcgb3IgRE1HIiwgIkVwZW5keW1vbWEiLCAiTWVzZW5jaHltYWwgdHVtb3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3RoZXIgQ05TIGVtYnJ5b25hbCB0dW1vciIsICJMb3ctZ3JhZGUgZ2xpb21hIikpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3Bsb3RfZ3JvdXArQ0xLMV9UUE1fZ3JvdXAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X0VGU19hZGRpdGl2ZV90ZXJtc19zdWJ0eXBlX2NsdXN0ZXJfY2xrMV90cG1fZ3JvdXAuUkRTIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJFRlNfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJFRlNfc3RhdHVzIikKCmZvcmVzdF9jN19jbGsxX2VmcyA8LSBwbG90Rm9yZXN0KHJlYWRSRFMoZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X0VGU19hZGRpdGl2ZV90ZXJtc19zdWJ0eXBlX2NsdXN0ZXJfY2xrMV90cG1fZ3JvdXAuUkRTIikpKQoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfRUZTX2NsdXN0ZXI3X2hpc3RvbG9neV9yZXNlY3Rpb25fY2xrMV90cG1fZ3JvdXAucGRmIiksCiAgICAgICBmb3Jlc3RfYzdfY2xrMV9lZnMsCiAgICAgICB3aWR0aCA9IDksIGhlaWdodCA9IDQsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQoKYWRkX21vZGVsX2M3X29zIDwtIGZpdF9zYXZlX21vZGVsKGNsdXN0ZXI3X2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcighZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbiAlaW4lIGMoIk5vdCBSZXBvcnRlZCIsICJVbmF2YWlsYWJsZSIpKSAlPiUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShwbG90X2dyb3VwID0gZmN0X3JlbGV2ZWwocGxvdF9ncm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIk90aGVyIGhpZ2gtZ3JhZGUgZ2xpb21hIiwgIkF0eXBpY2FsIFRlcmF0b2lkIFJoYWJkb2lkIFR1bW9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRJUEcgb3IgRE1HIiwgIkVwZW5keW1vbWEiLCAiTWVzZW5jaHltYWwgdHVtb3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3RoZXIgQ05TIGVtYnJ5b25hbCB0dW1vciIsICJMb3ctZ3JhZGUgZ2xpb21hIikpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3Bsb3RfZ3JvdXArQ0xLMV9UUE1fZ3JvdXAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X09TX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9jbGsxX3RwbV9ncm91cC5SRFMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXZhcmlhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcnNfY29sID0gIk9TX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiT1Nfc3RhdHVzIikKCmZvcmVzdF9jN19jbGsxX29zIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfT1NfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX2NsazFfdHBtX2dyb3VwLlJEUyIpKSkKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX09TX2NsdXN0ZXI3X2hpc3RvbG9neV9yZXNlY3Rpb25fY2xrMV90cG1fZ3JvdXAucGRmIiksCiAgICAgICBmb3Jlc3RfYzdfY2xrMV9vcywKICAgICAgIHdpZHRoID0gOSwgaGVpZ2h0ID0gNCwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCmBgYAoKQXNzZXNzIEVGUyBhbmQgT1MgYnkgQ0xLMSBQU0kgZ3JvdXAgaW4gbXVsdGl2YXJpYXRlIG1vZGVscyBhbmQgZ2VuZXJhdGUgZm9yZXN0IHBsb3RzCgpgYGB7cn0KYWRkX21vZGVsX2M3X2VmcyA8LSBmaXRfc2F2ZV9tb2RlbChjbHVzdGVyN19kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcihleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICE9ICJVbmF2YWlsYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDTEsxX1BTSV9ncm91cCAlaW4lIGMoIkhpZ2ggQ0xLMSBQU0kiLCAiTG93IENMSzEgUFNJIikpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUocGxvdF9ncm91cCA9IGZjdF9yZWxldmVsKHBsb3RfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJPdGhlciBoaWdoLWdyYWRlIGdsaW9tYSIsICJBdHlwaWNhbCBUZXJhdG9pZCBSaGFiZG9pZCBUdW1vciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJESVBHIG9yIERNRyIsICJFcGVuZHltb21hIiwgIk1lc2VuY2h5bWFsIHR1bW9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk90aGVyIENOUyBlbWJyeW9uYWwgdHVtb3IiLCAiTG93LWdyYWRlIGdsaW9tYSIpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rYWdlX2F0X2RpYWdub3Npc195ZWFycytwbG90X2dyb3VwK0NMSzFfUFNJX2dyb3VwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9FRlNfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX2NsazFfcHNpX2dyb3VwLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiRUZTX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIpCgpmb3Jlc3RfYzdfY2xrMV9lZnMgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9FRlNfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX2NsazFfcHNpX2dyb3VwLlJEUyIpKSkKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX0VGU19jbHVzdGVyN19oaXN0b2xvZ3lfcmVzZWN0aW9uX2NsazFfcHNpX2dyb3VwLnBkZiIpLAogICAgICAgZm9yZXN0X2M3X2NsazFfZWZzLAogICAgICAgd2lkdGggPSA5LCBoZWlnaHQgPSA0LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKCmFkZF9tb2RlbF9jN19vcyA8LSBmaXRfc2F2ZV9tb2RlbChjbHVzdGVyN19kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIoIWV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUocGxvdF9ncm91cCA9IGZjdF9yZWxldmVsKHBsb3RfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJPdGhlciBoaWdoLWdyYWRlIGdsaW9tYSIsICJBdHlwaWNhbCBUZXJhdG9pZCBSaGFiZG9pZCBUdW1vciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJESVBHIG9yIERNRyIsICJFcGVuZHltb21hIiwgIk1lc2VuY2h5bWFsIHR1bW9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk90aGVyIENOUyBlbWJyeW9uYWwgdHVtb3IiLCAiTG93LWdyYWRlIGdsaW9tYSIpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rYWdlX2F0X2RpYWdub3Npc195ZWFycytwbG90X2dyb3VwK0NMSzFfUFNJX2dyb3VwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9PU19hZGRpdGl2ZV90ZXJtc19zdWJ0eXBlX2NsdXN0ZXJfY2xrMV9wc2lfZ3JvdXAuUkRTIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJPU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIk9TX3N0YXR1cyIpCgpmb3Jlc3RfYzdfY2xrMV9vcyA8LSBwbG90Rm9yZXN0KHJlYWRSRFMoZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X09TX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9jbGsxX3BzaV9ncm91cC5SRFMiKSkpCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAiZm9yZXN0X2FkZF9PU19jbHVzdGVyN19oaXN0b2xvZ3lfcmVzZWN0aW9uX2NsazFfcHNpX2dyb3VwLnBkZiIpLAogICAgICAgZm9yZXN0X2M3X2NsazFfb3MsCiAgICAgICB3aWR0aCA9IDksIGhlaWdodCA9IDQsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQpgYGAKCkFzc2VzcyBFRlMgYW5kIE9TIGJ5IENMSzEgZXggNCBUUE0gaW4gbXVsdGl2YXJpYXRlIG1vZGVscyBhbmQgZ2VuZXJhdGUgZm9yZXN0IHBsb3RzCgpgYGB7cn0KYWRkX21vZGVsX2M3X2VmcyA8LSBmaXRfc2F2ZV9tb2RlbChjbHVzdGVyN19kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6OmZpbHRlcihleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICE9ICJVbmF2YWlsYWJsZSIpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUocGxvdF9ncm91cCA9IGZjdF9yZWxldmVsKHBsb3RfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJPdGhlciBoaWdoLWdyYWRlIGdsaW9tYSIsICJBdHlwaWNhbCBUZXJhdG9pZCBSaGFiZG9pZCBUdW1vciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJESVBHIG9yIERNRyIsICJFcGVuZHltb21hIiwgIk1lc2VuY2h5bWFsIHR1bW9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk90aGVyIENOUyBlbWJyeW9uYWwgdHVtb3IiLCAiTG93LWdyYWRlIGdsaW9tYSIpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rYWdlX2F0X2RpYWdub3Npc195ZWFycytwbG90X2dyb3VwK0NMSzFfRXg0X1RQTSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfRUZTX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9jbGsxX3RwbS5SRFMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXZhcmlhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcnNfY29sID0gIkVGU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIkVGU19zdGF0dXMiKQoKZm9yZXN0X2M3X2NsazFfZWZzIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfRUZTX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9jbGsxX3RwbS5SRFMiKSkpCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAiZm9yZXN0X2FkZF9FRlNfY2x1c3RlcjdfaGlzdG9sb2d5X3Jlc2VjdGlvbl9jbGsxX3RwbS5wZGYiKSwKICAgICAgIGZvcmVzdF9jN19jbGsxX2VmcywKICAgICAgIHdpZHRoID0gOSwgaGVpZ2h0ID0gNCwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCgphZGRfbW9kZWxfYzdfb3MgPC0gZml0X3NhdmVfbW9kZWwoY2x1c3RlcjdfZGYgJT4lIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKCFleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICVpbiUgYygiTm90IFJlcG9ydGVkIiwgIlVuYXZhaWxhYmxlIikpICU+JQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6bXV0YXRlKHBsb3RfZ3JvdXAgPSBmY3RfcmVsZXZlbChwbG90X2dyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygiT3RoZXIgaGlnaC1ncmFkZSBnbGlvbWEiLCAiQXR5cGljYWwgVGVyYXRvaWQgUmhhYmRvaWQgVHVtb3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRElQRyBvciBETUciLCAiRXBlbmR5bW9tYSIsICJNZXNlbmNoeW1hbCB0dW1vciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPdGhlciBDTlMgZW1icnlvbmFsIHR1bW9yIiwgIkxvdy1ncmFkZSBnbGlvbWEiKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtcyA9ICJleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uK2FnZV9hdF9kaWFnbm9zaXNfeWVhcnMrcGxvdF9ncm91cCtDTEsxX0V4NF9UUE0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X09TX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9jbGsxX3RwbS5SRFMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXZhcmlhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcnNfY29sID0gIk9TX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiT1Nfc3RhdHVzIikKCmZvcmVzdF9jN19jbGsxX29zIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfT1NfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX2NsazFfdHBtLlJEUyIpKSkKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX09TX2NsdXN0ZXI3X2hpc3RvbG9neV9yZXNlY3Rpb25fY2xrMV90cG0ucGRmIiksCiAgICAgICBmb3Jlc3RfYzdfY2xrMV9vcywKICAgICAgIHdpZHRoID0gOSwgaGVpZ2h0ID0gNCwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCmBgYAoKQXNzZXNzIEVGUyBhbmQgT1MgYnkgQ0xLMSBleCA0IFBTSSBpbiBtdWx0aXZhcmlhdGUgbW9kZWxzIGFuZCBnZW5lcmF0ZSBmb3Jlc3QgcGxvdHMKCmBgYHtyfQphZGRfbW9kZWxfYzdfZWZzIDwtIGZpdF9zYXZlX21vZGVsKGNsdXN0ZXI3X2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gIT0gIlVuYXZhaWxhYmxlIikgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShwbG90X2dyb3VwID0gZmN0X3JlbGV2ZWwocGxvdF9ncm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoIk90aGVyIGhpZ2gtZ3JhZGUgZ2xpb21hIiwgIkF0eXBpY2FsIFRlcmF0b2lkIFJoYWJkb2lkIFR1bW9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRJUEcgb3IgRE1HIiwgIkVwZW5keW1vbWEiLCAiTWVzZW5jaHltYWwgdHVtb3IiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiT3RoZXIgQ05TIGVtYnJ5b25hbCB0dW1vciIsICJMb3ctZ3JhZGUgZ2xpb21hIikpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3Bsb3RfZ3JvdXArQ0xLMV9leDRfUFNJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9FRlNfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX2NsazFfcHNpLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiRUZTX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIpCgpmb3Jlc3RfYzdfY2xrMV9lZnMgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9FRlNfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX2NsazFfcHNpLlJEUyIpKSkKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX0VGU19jbHVzdGVyN19oaXN0b2xvZ3lfcmVzZWN0aW9uX2NsazFfcHNpLnBkZiIpLAogICAgICAgZm9yZXN0X2M3X2NsazFfZWZzLAogICAgICAgd2lkdGggPSA5LCBoZWlnaHQgPSA0LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKCmFkZF9tb2RlbF9jN19vcyA8LSBmaXRfc2F2ZV9tb2RlbChjbHVzdGVyN19kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIoIWV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUocGxvdF9ncm91cCA9IGZjdF9yZWxldmVsKHBsb3RfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJPdGhlciBoaWdoLWdyYWRlIGdsaW9tYSIsICJBdHlwaWNhbCBUZXJhdG9pZCBSaGFiZG9pZCBUdW1vciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJESVBHIG9yIERNRyIsICJFcGVuZHltb21hIiwgIk1lc2VuY2h5bWFsIHR1bW9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk90aGVyIENOUyBlbWJyeW9uYWwgdHVtb3IiLCAiTG93LWdyYWRlIGdsaW9tYSIpKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rYWdlX2F0X2RpYWdub3Npc195ZWFycytwbG90X2dyb3VwK0NMSzFfZXg0X1BTSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfT1NfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX2NsazFfcHNpLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiT1NfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJPU19zdGF0dXMiKQoKZm9yZXN0X2M3X2NsazFfb3MgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9PU19hZGRpdGl2ZV90ZXJtc19zdWJ0eXBlX2NsdXN0ZXJfY2xrMV9wc2kuUkRTIikpKQoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfT1NfY2x1c3RlcjdfaGlzdG9sb2d5X3Jlc2VjdGlvbl9jbGsxX3BzaS5wZGYiKSwKICAgICAgIGZvcmVzdF9jN19jbGsxX29zLAogICAgICAgd2lkdGggPSA5LCBoZWlnaHQgPSA0LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKYGBgCgoKClByaW50IHNlc3Npb24gaW5mbwoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBg